﻿using MX.Core.Log;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Nop.Core.Configuration;
using Nop.Web.Services.Domain;
using Nop.Web.Services.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Nop.Web.Services.Factories
{
    //简易版规则引擎
    public interface IWalletRule
    {
        string Description { get; }
        string Name { get; }

        string FriedlyName { get; }

        List<WriteWalletQueueParameter.MemberPercent> Calc(IEnumerable<WalletRuleInfo> walletRuleInfos, long orderMemberId, NopConfig nopConfig);


        void Combin(Dictionary<string, List<WriteWalletQueueParameter.MemberPercent>> walletPercentMap);
    }


    public class WalletRuleUtils
    {
        static Dictionary<string, JObject> ruleMap = new Dictionary<string, JObject>();


        static public JObject GetRule(NopConfig nopConfig, string name)
        {
            try
            {
                if (ruleMap.Count < 1)
                {
                    var ruleJson = JsonConvert.DeserializeObject<JToken>(nopConfig.RuleConfigs);
                    if (ruleJson is JArray)
                    {
                        var ruleList = ruleJson as JArray;
                        foreach (var ruleToken in ruleList)
                        {
                            if (ruleToken.Type == JTokenType.Object)
                            {
                                var ruleObj = ruleToken as JObject;
                                if (ruleObj.ContainsKey("Name") && ruleObj.ContainsKey("Enable"))
                                {
                                    if (ruleObj["Name"].Type == JTokenType.String && ruleObj["Enable"].Type == JTokenType.Boolean)
                                    {
                                        var enable = ruleObj.Value<bool>("Enable");
                                        if (enable)
                                        {
                                            var ruleName = ruleObj.Value<string>("Name");
                                            ruleMap[ruleName] = ruleObj;
                                        }
                                    }
                                }
                            }

                        }
                    }
                }
                if (ruleMap.ContainsKey(name))
                {
                    return ruleMap[name];
                }
                else
                {
                    return null;
                }

            }
            catch (Exception ex)
            {
                Logger.Default.Error(ex, "规则解析发生错误");
                return null;

            }
        }
    }



    public class ChildRule : IWalletRule
    {
        public string Description => "用于计算团队业绩到多少,然后改变红包返还规则";

        public string Name => nameof(ChildRule);

        public string FriedlyName => "消费返还";

        public List<WriteWalletQueueParameter.MemberPercent> Calc(IEnumerable<WalletRuleInfo> walletRuleInfos, long orderMemberId, NopConfig nopConfig)
        {

            var ruleConfig = WalletRuleUtils.GetRule(nopConfig, Name);
            if (ruleConfig == null)
            {
                Logger.Default.Warn("规则[{0}]未找到配置", Name);
                return null;
            }
            if (!ruleConfig.ContainsKey("WalletLevelUp") || !ruleConfig.ContainsKey("NoramlPercent") || !ruleConfig.ContainsKey("UpPercent"))
            {
                Logger.Default.Warn("规则[{0}]配置错误,请检查WalletLevelUp,NoramlPercent,UpPercent", Name);
                return null;
            }
            var jsonWalletLevelUp = ruleConfig["WalletLevelUp"];
            var jsonNoramlPercent = ruleConfig["NoramlPercent"];
            var jsonUpPercent = ruleConfig["UpPercent"];
            if (jsonWalletLevelUp.Type != JTokenType.Integer)
            {
                Logger.Default.Warn("规则[{0}]配置错误,WalletLevelUp不为int", Name);
                return null;
            }
            if (jsonNoramlPercent.Type != JTokenType.Float)
            {
                Logger.Default.Warn("规则[{0}]配置错误,NoramlPercent不为float", Name);
                return null;
            }
            if (jsonUpPercent.Type != JTokenType.Float)
            {
                Logger.Default.Warn("规则[{0}]配置错误,UpPercent不为float", Name);
                return null;
            }
            int walletLevelUp = jsonWalletLevelUp.Value<int>();
            float noramlPercent = jsonNoramlPercent.Value<float>();
            float upPercent = jsonUpPercent.Value<float>();

            var ruleInfoList = JsonConvert.DeserializeObject<List<WalletRuleInfo>>(JsonConvert.SerializeObject(walletRuleInfos));
            ruleInfoList.RemoveAll(r => r.MemberId == orderMemberId);

            var levelUpList = ruleInfoList.Select(u => new
            {
                u.MemberId,
                u.OrderCount.CustomerId,
                LevelUp = u.OrderCount.ChildOrderAmount >= walletLevelUp
            });
            var levelUpMember = levelUpList.Where(l => l.LevelUp).FirstOrDefault();//最下级的升级
            if (levelUpMember != null && levelUpList.Where(l => l.LevelUp).Count() > 1)
            {
                levelUpList = levelUpList.Select(l => new { l.MemberId, l.CustomerId, LevelUp = levelUpMember.MemberId == l.MemberId });
            }
            var memberPercents = levelUpList.Select(l => new WriteWalletQueueParameter.MemberPercent()
            {
                CustomerId = l.CustomerId,
                HUC_MemberId = l.MemberId,
                Percent = l.LevelUp ? upPercent : noramlPercent
            }).ToList();
            var orderMemberInfo = levelUpList.FirstOrDefault();
            memberPercents.Add(new WriteWalletQueueParameter.MemberPercent()
            {
                CustomerId = orderMemberInfo.CustomerId,
                HUC_MemberId = orderMemberId,
                Percent = noramlPercent
            });
            return memberPercents;
        }

        public void Combin(Dictionary<string, List<WriteWalletQueueParameter.MemberPercent>> walletPercentMap)
        {

        }
    }

    public class CurrentRule : IWalletRule
    {
        public string FriedlyName => "二级分润";
        public string Description => "用于计算本级订单金额达到多少,然后改变红包返还规则";

        public string Name => nameof(CurrentRule);

        public List<WriteWalletQueueParameter.MemberPercent> Calc(IEnumerable<WalletRuleInfo> ruleInfoList, long orderMemberId, NopConfig nopConfig)
        {
            var ruleConfig = WalletRuleUtils.GetRule(nopConfig, Name);
            if (ruleConfig == null)
            {
                Logger.Default.Warn("规则[{0}]未找到配置", Name);
                return null;
            }
            if (!ruleConfig.ContainsKey("WalletLevelUp") || !ruleConfig.ContainsKey("UpPercent"))
            {
                Logger.Default.Warn("规则[{0}]配置错误,请检查WalletLevelUp,NoramlPercent,UpPercent", Name);
                return null;
            }
            var jsonWalletLevelUp = ruleConfig["WalletLevelUp"];

            var jsonUpPercent = ruleConfig["UpPercent"];
            if (jsonWalletLevelUp.Type != JTokenType.Integer)
            {
                Logger.Default.Warn("规则[{0}]配置错误,WalletLevelUp不为int", Name);
                return null;
            }

            if (jsonUpPercent.Type != JTokenType.Float)
            {
                Logger.Default.Warn("规则[{0}]配置错误,UpPercent不为float", Name);
                return null;
            }
            int walletLevelUp = jsonWalletLevelUp.Value<int>();
            float upPercent = jsonUpPercent.Value<float>();

            var levelUpList = ruleInfoList.Select(u => new
            {
                u.MemberId,
                u.OrderCount.CustomerId,
                LevelUp = u.OrderCount.OrderAmount >= walletLevelUp
            });

            List<WriteWalletQueueParameter.MemberPercent> memberPercents = new List<WriteWalletQueueParameter.MemberPercent>();
            var realyUpList = levelUpList.Where(l => l.LevelUp);
            foreach (var item in realyUpList)
            {
                Logger.Default.Debug("已升级用户:{0}", JsonConvert.SerializeObject(item));
            }
            var actionMember = realyUpList.Select(l => new WriteWalletQueueParameter.MemberPercent()
            {
                CustomerId = l.CustomerId,
                HUC_MemberId = l.MemberId,
                Percent = upPercent
            }).LastOrDefault();
            if (actionMember != null)
            {
                memberPercents.Add(actionMember);
            }
            return memberPercents;
        }

        public void Combin(Dictionary<string, List<WriteWalletQueueParameter.MemberPercent>> walletPercentMap)
        {
            //移除掉被本规则匹配掉了的用户
            if (walletPercentMap.ContainsKey(Name))
            {
                var walletPercent = walletPercentMap[Name];
                if (walletPercent != null && walletPercent.Count > 0)
                {
                    var memberPercent = walletPercent.FirstOrDefault();
                    if (memberPercent != null)
                    {
                        foreach (var name in walletPercentMap.Keys)
                        {
                            if (name != Name)
                            {
                                if (walletPercentMap[name] != null && walletPercentMap[name].Count > 0)
                                {
                                    walletPercentMap[name].RemoveAll(r => r.HUC_MemberId == memberPercent.HUC_MemberId);
                                }
                            }

                        }
                    }
                }
            }
        }
    }

}
